home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / russell / gc32.lha / new_hblk.c < prev    next >
C/C++ Source or Header  |  1993-06-25  |  6KB  |  231 lines

  1. /*
  2.  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  3.  * Copyright (c) 1991,1992 by Xerox Corporation.  All rights reserved.
  4.  *
  5.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  6.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  7.  *
  8.  * Permission is hereby granted to copy this garbage collector for any purpose,
  9.  * provided the above notices are retained on all copies.
  10.  *
  11.  * This file contains the functions:
  12.  *    ptr_t GC_build_flXXX(h, old_fl)
  13.  *    void GC_new_hblk(n)
  14.  */
  15.  
  16.  
  17. # include <stdio.h>
  18. # include "gc_private.h"
  19.  
  20. /*
  21.  * Build a free list for size 1 objects inside hblk h.  Set the last link to
  22.  * be ofl.  Return a pointer tpo the first free list entry.
  23.  */
  24. ptr_t GC_build_fl1(h, ofl)
  25. struct hblk *h;
  26. ptr_t ofl;
  27. {
  28.     register word * p = (word *)h;
  29.     register word * lim = (word *)(h + 1);
  30.     
  31.     p[0] = (word)ofl;
  32.     p[1] = (word)(p);
  33.     p[2] = (word)(p+1);
  34.     p[3] = (word)(p+2);
  35.     p += 4;
  36.     for (; p < lim; p += 4) {
  37.         p[0] = (word)(p-1);
  38.         p[1] = (word)(p);
  39.         p[2] = (word)(p+1);
  40.         p[3] = (word)(p+2);
  41.     };
  42.     return((ptr_t)(p-1));
  43. }
  44.  
  45. /* The same for size 2 cleared objects */
  46. ptr_t GC_build_fl_clear2(h, ofl)
  47. struct hblk *h;
  48. ptr_t ofl;
  49. {
  50.     register word * p = (word *)h;
  51.     register word * lim = (word *)(h + 1);
  52.     
  53.     p[0] = (word)ofl;
  54.     p[1] = 0;
  55.     p[2] = (word)p;
  56.     p[3] = 0;
  57.     p += 4;
  58.     for (; p < lim; p += 4) {
  59.         p[0] = (word)(p-2);
  60.         p[1] = 0;
  61.         p[2] = (word)p;
  62.         p[3] = 0;
  63.     };
  64.     return((ptr_t)(p-2));
  65. }
  66.  
  67. /* The same for size 3 cleared objects */
  68. ptr_t GC_build_fl_clear3(h, ofl)
  69. struct hblk *h;
  70. ptr_t ofl;
  71. {
  72.     register word * p = (word *)h;
  73.     register word * lim = (word *)(h + 1) - 2;
  74.     
  75.     p[0] = (word)ofl;
  76.     p[1] = 0;
  77.     p[2] = 0;
  78.     p += 3;
  79.     for (; p < lim; p += 3) {
  80.         p[0] = (word)(p-3);
  81.         p[1] = 0;
  82.         p[2] = 0;
  83.     };
  84.     return((ptr_t)(p-3));
  85. }
  86.  
  87. /* The same for size 4 cleared objects */
  88. ptr_t GC_build_fl_clear4(h, ofl)
  89. struct hblk *h;
  90. ptr_t ofl;
  91. {
  92.     register word * p = (word *)h;
  93.     register word * lim = (word *)(h + 1);
  94.     
  95.     p[0] = (word)ofl;
  96.     p[1] = 0;
  97.     p[2] = 0;
  98.     p[3] = 0;
  99.     p += 4;
  100.     for (; p < lim; p += 4) {
  101.         p[0] = (word)(p-4);
  102.         p[1] = 0;
  103.         p[2] = 0;
  104.         p[3] = 0;
  105.     };
  106.     return((ptr_t)(p-4));
  107. }
  108.  
  109. /* The same for size 2 uncleared objects */
  110. ptr_t GC_build_fl2(h, ofl)
  111. struct hblk *h;
  112. ptr_t ofl;
  113. {
  114.     register word * p = (word *)h;
  115.     register word * lim = (word *)(h + 1);
  116.     
  117.     p[0] = (word)ofl;
  118.     p[2] = (word)p;
  119.     p += 4;
  120.     for (; p < lim; p += 4) {
  121.         p[0] = (word)(p-2);
  122.         p[2] = (word)p;
  123.     };
  124.     return((ptr_t)(p-2));
  125. }
  126.  
  127. /* The same for size 4 uncleared objects */
  128. ptr_t GC_build_fl4(h, ofl)
  129. struct hblk *h;
  130. ptr_t ofl;
  131. {
  132.     register word * p = (word *)h;
  133.     register word * lim = (word *)(h + 1);
  134.     
  135.     p[0] = (word)ofl;
  136.     p[4] = (word)p;
  137.     p += 8;
  138.     for (; p < lim; p += 8) {
  139.         p[0] = (word)(p-4);
  140.         p[4] = (word)p;
  141.     };
  142.     return((ptr_t)(p-4));
  143. }
  144.  
  145.  
  146. /*
  147.  * Allocate a new heapblock for small objects of size n.
  148.  * Add all of the heapblock's objects to the free list for objects
  149.  * of that size.  Will fail to do anything if we are out of memory.
  150.  */
  151. void GC_new_hblk(sz, kind)
  152. register word sz;
  153. int kind;
  154. {
  155.     register word *p,
  156.           *prev;
  157.     word *last_object;        /* points to last object in new hblk    */
  158.     register struct hblk *h;    /* the new heap block            */
  159.     register bool clear = GC_obj_kinds[kind].ok_init;
  160.  
  161. #   ifdef PRINTSTATS
  162.     if ((sizeof (struct hblk)) > HBLKSIZE) {
  163.         abort("HBLK SZ inconsistency");
  164.         }
  165. #   endif
  166.  
  167.   /* Allocate a new heap block */
  168.     h = GC_allochblk(sz, kind);
  169.     if (h == 0) return;
  170.  
  171.   /* Handle small objects sizes more efficiently.  For larger objects     */
  172.   /* the difference is less significant.                */
  173.     switch (sz) {
  174.         case 1: GC_obj_kinds[kind].ok_freelist[1] =
  175.               GC_build_fl1(h, GC_obj_kinds[kind].ok_freelist[1]);
  176.             return;
  177.         case 2: if (clear) {
  178.                  GC_obj_kinds[kind].ok_freelist[2] =
  179.                   GC_build_fl_clear2(h, GC_obj_kinds[kind].ok_freelist[2]);
  180.             } else {
  181.                 GC_obj_kinds[kind].ok_freelist[2] =
  182.                   GC_build_fl2(h, GC_obj_kinds[kind].ok_freelist[2]);
  183.             }
  184.             return;
  185.         case 3: if (clear) {
  186.                  GC_obj_kinds[kind].ok_freelist[3] =
  187.                   GC_build_fl_clear3(h, GC_obj_kinds[kind].ok_freelist[3]);
  188.                 return;
  189.             } else {
  190.                 /* It's messy to do better than the default here. */
  191.                 break;
  192.             }
  193.         case 4: if (clear) {
  194.                 GC_obj_kinds[kind].ok_freelist[4] =
  195.                   GC_build_fl_clear4(h, GC_obj_kinds[kind].ok_freelist[4]);
  196.             } else {
  197.                 GC_obj_kinds[kind].ok_freelist[4] =
  198.                   GC_build_fl4(h, GC_obj_kinds[kind].ok_freelist[4]);
  199.             }
  200.             return;
  201.         default:
  202.             break;
  203.     }
  204.     
  205.   /* Clear the page if necessary. */
  206.     if (clear) bzero((char *)h, (int)HBLKSIZE);
  207.     
  208.   /* Add objects to free list */
  209.     p = &(h -> hb_body[sz]);    /* second object in *h    */
  210.     prev = &(h -> hb_body[0]);           /* One object behind p    */
  211.     last_object = ((word *)((char *)h + HBLKSIZE)) - sz;
  212.                 /* Last place for last object to start */
  213.  
  214.   /* make a list of all objects in *h with head as last object */
  215.     while (p <= last_object) {
  216.       /* current object's link points to last object */
  217.         obj_link(p) = (ptr_t)prev;
  218.     prev = p;
  219.     p += sz;
  220.     }
  221.     p -= sz;            /* p now points to last object */
  222.  
  223.   /*
  224.    * put p (which is now head of list of objects in *h) as first
  225.    * pointer in the appropriate free list for this size.
  226.    */
  227.       obj_link(h -> hb_body) = GC_obj_kinds[kind].ok_freelist[sz];
  228.       GC_obj_kinds[kind].ok_freelist[sz] = ((ptr_t)p);
  229. }
  230.  
  231.